package org.studiox.graph.common;

import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.lang.StringUtils;
import org.studiox.graph.common.exception.GraphException;

import java.net.URL;

import static org.studiox.graph.common.GraphConstant.ConfigConstant.CONFIG_FILE_NAME;
import static org.studiox.graph.common.GraphConstant.JanusGraphConfigConstant.CONFIG_PREFIX;
import static org.studiox.graph.common.exception.GraphExceptionCode.*;

public class GraphConfig {

  private static volatile Configuration config = null;

  public static void forceReload() {
    if (config != null) {
      synchronized (GraphConfig.class) {
        if (config != null) {
          config = null;
        }
      }
    }
  }

  private static Configuration getConfig(String fileName) throws GraphException {
    if (StringUtils.isBlank(fileName)) {
      return null;
    }
    URL url = GraphConfig.class.getClassLoader().getResource(fileName);
    if (null == url) {
      url = GraphConfig.class.getClassLoader().getResource("/" + fileName);
    }
    if (null == url) {
      throw new GraphException("Config fileName='" + fileName + "'", CONFIG_FILE_NOT_EXIST);
    }
    try {
      return new PropertiesConfiguration(url);
    } catch (ConfigurationException e) {
      throw new GraphException(e.getMessage(), e, CONFIG_FORMAT_NOT_CORRECT);
    }
  }

  private static Configuration buildDefaultGraphConfig() throws GraphException {
    config = getConfig(CONFIG_FILE_NAME);
    try {
      return config.subset(CONFIG_PREFIX);
    } catch (Throwable t) {
      throw new GraphException("Config prefix='" + CONFIG_PREFIX + "'", CONFIG_PREFIX_NOT_EXIST);
    }
  }

  public static Configuration getGraphConfig() throws GraphException {
    if (config == null) {
      synchronized (GraphConfig.class) {
        if (config == null) {
          config = buildDefaultGraphConfig();
        }
      }
    }
    return config;
  }
}
